Copy files
How can I copy files in Delphi ?
If you want to make a typical copy of a file; simply you can use CopyFile API function,
but if you want to encrypt a file while copying or add a header to the file or any
other modification; you have to copy files manually by using untyped file.
Copy files using CopyFile:
- Drop two Edit boxes and a Button.
- At Button's OnClick event write:
CopyFile(PChar(Edit1.Text),
PChar(Edit2.Text), false);
After running, enter a source file name in Edit1, and a destination file name in
Edit2 then press the button.
As you might know, API functions always deal with null-terminated strings, so that
you have to typecast any string to a PChar. PChar represents null-terminated string
in Delphi and Pascal.
If last parameter is False; copy will not care about destination file existance,
it will overwrite destination file if it is exists. If this parameter is Ture; the
copy function will fail if destination file is exists.
Copy file returns True if success and False if failed.
Copy files using untyped file
As I've said you can copy files manually using untyped file in cases you need to
perform some modification to files such as: encryption, compression, add header to
a file, and file transfer.
Reading and writing from and to untyped files done by BlockRead and BlockWrite procedures
(For more information about untyped file see Programming with Turbo Pascal 7 Electronic
book).
- Drop two Edit boxes and a Button.
- Write this procedure:
function FCopy(SourceName, TargetName: string): boolean;
var
SourceF, TargetF: file;
Buf: array [0 .. 1023] of byte;
NumRead: integer;
begin
Result:= false;
try
AssignFile(SourceF, SourceName);
AssignFile(TargetF, TargetName);
FileMode:= 0; // Read only
Reset(SourceF, 1); // Record size = 1 byte
Rewrite(TargetF, 1); // Create target file (destination)
{ You can write header here, such as: }
{ MyHeader:= 6 // MyHeader is an integer }
{ BlockWrite(TargetF, MyHeader, SizeOf(MyHeader)); }
(*** Coping ***)
while not Eof(SourceF) do
begin
BlockRead(SourceF, Buf, SizeOf(Buf), NumRead);
{ You can perform any modification to Buf here such as: }
{ Encrypt(Buf, NumRead); // Suppose that Encrypt is a procedure }
BlockWrite(TargetF, Buf, NumRead);
end; // while not Eof..
CloseFile(SourceF);
CloseFile(TargetF);
Result:= True;
except
on E: EInOutError do
begin
MessageDlg(E.Message, mtError, [mbOk], 0);
exit;
end; // on E:..
end; // try
end;
- At Button's OnClick event write:
if FCopy(Edit1.Text, Edit2.Text) then
MessageDlg('File copied successfully', mtInformation, [mbOk], 0)
else
MessageDlg('Error while coping file', mtError, [mbOk], 0);
Run this program and test it. FCopy procedure works properly, isn't it ? The answer
is NO, some thing is missing, there is a big difference between source and target
file, didn't you observe it ? If you did not, try to check it now and see both files
information. Look at files date! Source and target files date are different, we forget
to copy it. When we create a file current date and time will be set to new file as
an updated time, so how can we copy file date and time ?
The answer is very simple, by using FileAge and FileSetDate functions. FileAge returns
file date and time, we can use it to get source file date and time. FileSetDate sets
file date and time, so that we can use it to set target file date and time. FCopy
function will be: ( Additions written in Red color )
function FCopy(SourceName, TargetName: string): boolean;
var
SourceF, TargetF: file;
Buf: array [0 .. 1023] of byte;
NumRead: integer;
Age, Handle: integer;
begin
Result:= false;
try
AssignFile(SourceF, SourceName);
AssignFile(TargetF, TargetName);
FileMode:= 0; // Read only
Reset(SourceF, 1); // Record size = 1 byte
Rewrite(TargetF, 1); // Create target file (destination)
{ You can write header here, such as: }
{ MyHeader:= 6 // MyHeader is an integer }
{ BlockWrite(TargetF, MyHeader, SizeOf(MyHeader)); }
(*** Coping ***)
while not Eof(SourceF) do
begin
BlockRead(SourceF, Buf, SizeOf(Buf), NumRead);
{ You can perform any modification to Buf here such as: }
{ Encrypt(Buf, NumRead); // Suppose that Encrypt is a procedure }
BlockWrite(TargetF, Buf, NumRead);
end; // while not Eof..
CloseFile(SourceF);
CloseFile(TargetF);
(*** Copy file date and time ***)
Age:= FileAge(SourceName);
Handle:= FileOpen(TargetName, fmOpenWrite);
FileSetDate(Handle, Age);
FileClose(Handle);
Result:= True;
except
on E: EInOutError do
begin
MessageDlg(E.Message, mtError, [mbOk], 0);
exit;
end; // on E:..
end; // try
end;
See also
Untyped files